package com.hcms.admin.controller.sys;

import cn.hutool.core.bean.BeanUtil;
import com.hcms.admin.annotation.CheckPermission;
import com.hcms.admin.dto.*;
import com.hcms.admin.service.ISysAdminService;
import com.hcms.common.api.CommonPage;
import com.hcms.common.api.CommonResponse;
import com.hcms.common.config.CmsJwtProperties;
import com.hcms.mybatis.entity.SysAdmin;
import com.hcms.mybatis.entity.SysRole;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 后台用户表 前端控制器
 * </p>
 *
 * @author achenxw@126.com
 * @since 2023-02-13
 */
@RestController
@RequestMapping("/sysAdmin")
@Api
public class SysAdminController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private CmsJwtProperties jwtConfig;

    @Autowired
    private ISysAdminService sysAdminService;

    @ApiOperation(value = "登录后获取用户基本信息")
    @GetMapping("/info")
    @CheckPermission(check = false)
    @ResponseBody
    public ResponseEntity<CommonResponse<SysAdminInfoResponse>> info() {
        logger.info("Run info()");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if (principal instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) principal;
            String username = userDetails.getUsername();
            logger.info("Get user base data, username={}", username);
            SysAdminInfoResponse info = sysAdminService.getInfo(username);
            logger.info("Obtaining basic user information succeeded");
            return CommonResponse.ok(info);
        } else {
            logger.error("Failed to obtain user basic data");
            return CommonResponse.badRequest("获取数据失败");
        }
    }

    @ApiOperation("刷新token")
    @GetMapping("/refreshToken")
    @CheckPermission(check = false)
    @ResponseBody
    public ResponseEntity<CommonResponse<SysAdminLoginResponse>> refreshToken(HttpServletRequest request) {
        logger.info("Run refreshToken()");
        String oldToken = request.getHeader(jwtConfig.getTokenHeader());
        String token = oldToken.substring(jwtConfig.getTokenPrefix().length());
        String newToken = sysAdminService.refreshToken(token);
        SysAdminLoginResponse result = SysAdminLoginResponse.builder().tokenPrefix(jwtConfig.getTokenPrefix()).token(newToken).build();
        logger.info("Generate a new token end");
        return CommonResponse.ok(result);
    }

    @ApiOperation("获取用户列表")
    @GetMapping("")
    @ResponseBody
    public ResponseEntity<CommonResponse<CommonPage<SysAdminResponse>>> index(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Integer status,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize
    ) {
        logger.info("Run index(), keyword={}, status={}, pageNum={}, pageSize={}", keyword, status, pageNum, pageSize);
        List<SysAdmin> list = sysAdminService.getList(keyword, status, pageNum, pageSize);
        List<SysAdminResponse> result = list.stream().map(itm -> BeanUtil.copyProperties(itm, SysAdminResponse.class)).collect(Collectors.toList());
        return CommonResponse.ok(CommonPage.restPage(result));
    }

    @ApiOperation("获取用户信息")
    @GetMapping("/{id}")
    @ResponseBody
    public ResponseEntity<CommonResponse<SysAdminResponse>> view(@PathVariable Long id) {
        logger.info("Run view(), id={}", id);
        SysAdmin item = sysAdminService.getView(id);
        if (item == null) {
            logger.error("The user does not exist");
            return CommonResponse.notFound("记录不存在");
        }
        SysAdminResponse result = BeanUtil.copyProperties(item, SysAdminResponse.class);
        return CommonResponse.ok(result);
    }

    @ApiOperation("添加用户")
    @PostMapping("")
    @ResponseBody
    public ResponseEntity<CommonResponse<SysAdmin>> create(@RequestBody SysAdmin entity) {
        logger.info("Run create(), username={}", entity.getUsername());
        int count = sysAdminService.createItem(entity);
        if (count > 0) {
            logger.info("Adding a user succeeded");
            return CommonResponse.created(entity);
        } else {
            logger.error("Adding a user fails");
            return CommonResponse.badRequest("添加失败");
        }
    }

    @ApiOperation("更新用户")
    @PutMapping("/{id}")
    @ResponseBody
    public ResponseEntity<CommonResponse<SysAdmin>> update(@PathVariable Long id, @RequestBody SysAdmin entity) {
        logger.info("Run update(), id={}", id);
        int count = sysAdminService.updateItem(id, entity);
        if (count > 0) {
            logger.info("Update user data success");
            return CommonResponse.accepted("更新成功");
        } else {
            logger.error("Update user data failed");
            return CommonResponse.badRequest("更新失败");
        }
    }

    @ApiOperation("删除用户")
    @DeleteMapping("/{ids}")
    @ResponseBody
    public ResponseEntity<CommonResponse<Object>> delete(@PathVariable String ids) {
        logger.info("Run delete(), ids={}", ids);
        int count = sysAdminService.deleteItem(ids);
        if (count > 0) {
            logger.info("Delete user success");
            return CommonResponse.noContent("删除成功");
        } else {
            logger.info("Delete user failed");
            return CommonResponse.badRequest("删除失败");
        }
    }

    @ApiOperation("获取用户角色")
    @GetMapping("/adminRoles")
    @ResponseBody
    public ResponseEntity<CommonResponse<Collection<SysRole>>> adminRoles(@RequestParam Long adminId) {
        logger.info("Run getRoles(), adminId={}", adminId);
        Collection<SysRole> roles = sysAdminService.getAdminRoles(adminId);
        return CommonResponse.ok(roles);
    }

    @ApiOperation("设置用户角色")
    @PostMapping("/adminRoles")
    @ResponseBody
    public boolean adminRoles(@RequestParam Long adminId, @RequestParam String roles) {
        logger.info("Run setRole(), adminId={}, roles={}", adminId, roles);
        return sysAdminService.setAdminRoles(adminId, roles);
    }


    @ApiOperation("获取管理员options")
    @GetMapping("/options")
    @ResponseBody
    @CheckPermission(check = false)
    public ResponseEntity<CommonResponse<List<SysAdminOptionResponse>>> options() {
        List<SysAdmin> list = sysAdminService.list();
        List<SysAdminOptionResponse> collect = list.stream().map(SysAdminOptionResponse::new).collect(Collectors.toList());
        return CommonResponse.ok(collect);
    }

//    @ApiOperation("导出用户")
//    @GetMapping("/export")
//    public void export(
//            @RequestParam(required = false) String keyword,
//            @RequestParam(required = false) Integer status,
//            HttpServletResponse response
//    ) throws IOException {
//        logger.info("Run export()");
//        // 获取内容
//        List<SysAdmin> list = sysAdminService.getList(keyword, status, 1, 10000);
//        List<SysAdminResponse> adminList = list.stream().map(itm -> BeanUtil.copyProperties(itm, SysAdminResponse.class)).collect(Collectors.toList());
//        //输出内容
//        String filename = "sys-admin-" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//        response.setHeader("Content-Disposition", "attachment;filename=" + filename + ".xlsx");
//        ExcelWriter writer = ExcelUtil.getWriter();
//        writer.write(adminList);
//        writer.flush(response.getOutputStream(), true);
//        writer.close();
//    }

}
